{% extends "./base.html" %}

{% load admin_utils %}

{% block main_content %}
<div id="audit-operations-wrapper">
    <!--  操作详情弹窗  -->
    <bk-dialog header-position="left" v-model="detailVisible" theme="primary" width="1000">
        <div slot="header">操作详情</div>
        <bk-form>
            <bk-container flex :col="2">
                <bk-row>
                    <bk-col :span="1">
                        <bk-form-item label="操作类型">
                            <bk-input v-model="detailData.operation" :readonly="true" placeholder="--"></bk-input>
                        </bk-form-item>
                    </bk-col>
                    <bk-col :span="1">
                        <bk-form-item label="状态">
                            <bk-input v-model="detailData.result_type" :readonly="true" placeholder="--"></bk-input>
                        </bk-form-item>
                    </bk-col>
                </bk-row>
                <bk-row>
                    <bk-col :span="1">
                        <bk-form-item label="操作对象">
                            <bk-input v-model="detailData.target" :readonly="true" placeholder="--"></bk-input>
                        </bk-form-item>
                    </bk-col>
                    <bk-col :span="1">
                        <bk-form-item label="应用 ID">
                            <bk-input v-model="detailData.app_code" :readonly="true" placeholder="--"></bk-input>
                        </bk-form-item>
                    </bk-col>
                </bk-row>
                <bk-row>
                    <bk-col :span="1">
                        <bk-form-item label="操作人">
                            <bk-input v-model="detailData.operator" :readonly="true" placeholder="--"></bk-input>
                        </bk-form-item>
                    </bk-col>
                    <bk-col :span="1">
                        <bk-form-item label="操作方式">
                            <bk-input v-model="detailData.access_type" :readonly="true" placeholder="--"></bk-input>
                        </bk-form-item>
                        </bk-col>
                </bk-row>
                <bk-row>
                    <bk-col :span="1">
                        <bk-form-item label="模块">
                            <bk-input v-model="detailData.module_name" :readonly="true" placeholder="--"></bk-input>
                        </bk-form-item>
                    </bk-col>
                    <bk-col :span="1">
                        <bk-form-item label="环境">
                            <bk-input v-model="detailData.environment" :readonly="true" placeholder="--"></bk-input>
                        </bk-form-item>
                    </bk-col>
                </bk-row>
                <bk-row>
                    <bk-col :span="1">
                        <bk-form-item label="操作时间">
                            <bk-input v-model="detailData.at" :readonly="true" placeholder="--"></bk-input>
                        </bk-form-item>
                    </bk-col>
                </bk-row>
                <bk-row>
                    <bk-col :span="1">
                        <bk-form-item label="操作前"></bk-form-item>
                    </bk-col>
                    <bk-col :span="1">
                        <bk-form-item label="操作后"></bk-form-item>
                    </bk-col>
                </bk-row>
                <template>
                    <bk-diff :old-content="detailData.data_before" :new-content="detailData.data_after" :format="'side-by-side'" language="text"></bk-diff>
                </template>
            </bk-container>
        </bk-form>
    </bk-dialog>

    <!--  搜索框  -->
    <div class="toolbar" style="justify-content: space-between; display: flex; align-items:center;">
        <div class="paas-search" style="width: 400px;">
            <bk-input
                placeholder="输入应用 ID，按 Enter 搜索"
                :clearable="true"
                :right-icon="'bk-icon icon-search'"
                v-model="filterKey"
                @enter="refreshPage">
            </bk-input>
        </div>
    </div>

    <!--  操作审计 Table  -->
    <bk-table class="mt15" :data="app_audit_records">
        <bk-table-column label="操作类型">
            <template slot-scope="props">
                <span>$[ getOperationType(props.row.operation) ]</span>
            </template>
        </bk-table-column>
        <bk-table-column label="操作对象">
            <template slot-scope="props">
                <span>$[ getTargetType(props.row.target) ]</span>
            </template>
        </bk-table-column>
        <bk-table-column label="应用 ID">
            <template slot-scope="props">
                <span>$[ props.row.app_code ]</span>
            </template>
        </bk-table-column>
        <bk-table-column label="模块">
            <template slot-scope="props">
                <span>$[ props.row.module_name || '--' ] </span>
            </template>
        </bk-table-column>
        <bk-table-column label="环境">
            <template slot-scope="props">
                <span>$[ getEnvType(props.row.environment) || '--' ] </span>
            </template>
        </bk-table-column>
        <bk-table-column label="操作时间">
            <template slot-scope="props">
                <span>$[ props.row.at ]</span>
            </template>
        </bk-table-column>
        <bk-table-column label="状态">
            <template slot-scope="props">
                <span>$[ getResultType(props.row.result_code) ]</span>
            </template>
        </bk-table-column>
        <bk-table-column label="操作人" prop="operator">
            <template slot-scope="props">
                <span>$[ props.row.operator ]</span>
            </template>
        </bk-table-column>
        <bk-table-column label="操作">
            <template slot-scope="props">
                <bk-button class="ml5" theme="primary" text @click="showDetailDialog(props.row.uuid)">详情</bk-button>
            </template>
        </bk-table-column>
    </bk-table>
    <pagination
        class="mt15"
        :current.sync="pagination.curPage"
        :limit="pagination.limit"
        :count="pagination.count"
        :align="'right'"
    />
</div>
{% endblock %}

{% block main_script %}
<script type="text/javascript" charset="utf-8">
    var URLRouter = {
        detail: decodeURI("{% url 'admin.audit.app.detail' '${id}' %}"),
    }

    const result_types = {{ result_types | to_json }}

    const access_types = {{ access_types | to_json }}

    const target_types = {{ target_types | to_json }}

    const operation_types = {{ operation_types | to_json }}

    const app_audit_records = {{ app_audit_records | to_json }}

    const pagination = {{ pagination | to_json }}

    const env_types = {{ env_types | to_json }}

    const getResultType = function (value) {
        for(key of Object.keys(result_types)){
            if(key === String(value)){
                return result_types[key]
            }
        }
    }

    const getAccessType = function (value) {
        for(key of Object.keys(access_types)){
            if(key === String(value)){
                return access_types[key]
            }
        }
    }

    const getOperationType = function (value) {
        for(key of Object.keys(operation_types)){
            if(key === String(value)){
                return operation_types[key]
            }
        }
    }

    const getTargetType = function (value) {
        for(key of Object.keys(target_types)){
            if(key === String(value)){
                return target_types[key]
            }
        }
    }

    const getEnvType = function (value) {
        for(key of Object.keys(env_types)){
            if(key === String(value)){
                return env_types[key]
            }
        }
    }

    document.addEventListener('DOMContentLoaded', () => {
        new Vue({
            el: "#audit-operations-wrapper",
            delimiters: ['$[', ']'],
            data: function () {
                return {
                    loading: false,
                    loaded: false,
                    detailVisible: false,
                    filterKey: '',
                    app_audit_records: app_audit_records,
                    detailData: {
                        operation: '',
                        result_type: '',
                        app_code: '',
                        module_name: '',
                        operator: '',
                        access_type: '',
                        data_before: '',
                        data_after: '',
                        environment: '',
                    },
                    result_types,
                    access_types,
                    pagination: pagination,
                }
            },
            created: function () {
                const urlParams = new URLSearchParams(window.location.search);
                if (urlParams.has('filter_key')) {
                    this.filterKey = urlParams.get('filter_key');
                }
            },
            methods: {
                refreshPage: function () {
                    const urlParams = new URLSearchParams(window.location.search);
                    urlParams.set('limit', this.pagination.limit);
                    urlParams.set('filter_key', this.filterKey)
                    urlParams.set('offset', '0');
                    window.location.href = '?' + urlParams.toString();
                },
                showDetailDialog: async function (id) {
                    const el = this.$bkLoading({title: '加载中'});
                    const url = URLRouter.detail.replace('${id}', id);
                    try {
                        await this.$http.get(url).then(res => {
                            this.detailData = res;
                            this.detailData.result_type = getResultType(res.result_code);
                            this.detailData.access_type = getAccessType(res.access_type);
                            this.detailData.operation = getOperationType(res.operation);
                            this.detailData.target = getTargetType(res.target);
                            this.detailData.environment = getEnvType(res.environment);
                            if (res.data_before) {
                                res.data_before.data = this.sortObjectKeys(res.data_before.data);
                                this.detailData.data_before = JSON.stringify(res.data_before.data, null, 4);
                            }
                            if (res.data_after) {
                                res.data_after.data = this.sortObjectKeys(res.data_after.data);
                                this.detailData.data_after = JSON.stringify(res.data_after.data, null, 4);
                            }
                        });
                    } catch (e) {
                        this.$bkMessage({
                            theme: 'error',
                            message: e.response.data.detail,
                        });
                    } finally {
                        el.hide = true;
                        this.detailVisible = true;
                    }
                },
                sortObjectKeys: function(obj) {
                    if (Array.isArray(obj)) {
                        return obj.map(this.sortObjectKeys);
                    } else if (obj !== null && typeof obj === 'object') {
                        const sortedObj = {};
                        Object.keys(obj).sort().forEach(key => {
                            sortedObj[key] = this.sortObjectKeys(obj[key]);
                        });
                        return sortedObj;
                    }
                    return obj;
                },
                getResultType,
                getAccessType,
                getTargetType,
                getOperationType,
                getEnvType,
            }
        })
    })
</script>
<style>
    .bk-grid-row + .bk-grid-row {
        margin-top: 20px;
    }
</style>
{% endblock %}
